/*
ID: icerupt1
PROG: agrinet
LANG: C++11
*/

/* solution
 *
 * Minimal Spanning Trees
 *
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>

std::ifstream fin {"agrinet.in" };
std::ofstream fout{"agrinet.out"};

struct edge { int c, u, v; };

bool operator<(edge a, edge b)
{
	return a.c < b.c;
}

std::vector<edge> e;

int const maxn = 102;
int map[maxn][maxn];
int father[maxn], rank[maxn];
int n;

int getfather(int x)
{
	return (x == father[x]) ? x : (x = getfather(father[x]));
}

void merge(int x, int y)
{
	int u = getfather(x), v = getfather(y);
	if (u != v) {
		if (rank[v] < rank[u]) father[v] = u;
		else {
			father[u] = v;
			if (rank[u] == rank[v]) rank[v]++;
		}
	}
}

int main()
{
	fin >> n;
	for (auto i = 0; i < n; i++)
		for (auto j = 0; j < n; j++) {
			fin >> map[i][j];
			if (i != j)
				e.push_back({map[i][j], i, j});
		}

	for (int i = 0; i < n; i++) father[i] = i;
	std::sort(e.begin(), e.end());

	int ans = 0;
	for (auto i : e) {
		if (getfather(i.u) != getfather(i.v)) {
			merge(i.u, i.v);
			ans += i.c;
		}
	}
	std::cout << ans << '\n';
	fout << ans << '\n';
}
